//
//  DataBoss.m
//  数据请求封装
//
//  Created by ju on 14-7-10.
//  Copyright (c) 2014年 scics. All rights reserved.
//  修改日志
//  日期       人  描述
//  2014.9.3  ju  sendAsynchronousRequest:系列方法里面缺少对|请求超时|等错误的处理，新增setFailedBlock:修复
//  2014.9.3  ju  增加请求和缓存图片方法，默认保存到document的resources下
//  2014.9.4  ju  请求图片时先判断是否已经缓存，如果缓存则直接返回缓存结果

#import "DataBoss.h"
#import "Reachability.h"
#import "ASIDownloadCache.h"
#import "ASIFormDataRequest.h"
#import <CommonCrypto/CommonDigest.h>
#define PAGESIZE 3

const int kDataBossDefaultTimeOut = 10;


NSString * const kDataBossFileTypeJPEG = @"image/jpeg";
NSString * const kDataBossFileTypePNG = @"image/png";
NSString * const kDataBossFileTypeMP4 = @"video/mp4";

static ASIDownloadCache *downloadCache = nil;
@implementation DataBoss
{
    BOOL _hasMore;
    
    Reachability *reach;
    
    ASIHTTPRequest *request;
    
    BOOL _lock;
}
@synthesize page;


- (id)init
{
    self = [super init];
    if (self) {
        page = 1;
        reach = [Reachability reachabilityForInternetConnection];
        _hasMore = YES;
        _lock = NO;
        _limit = (_limit==0?PAGESIZE:_limit);
        _timeout = 10;
        _limit = 10;
    }
    return self;
}

- (id)initWithAction:(NSString *)theAction
{
    self = [self init];
    if (self) {
        _action = theAction;
    }
    return self;
}

/*
 - (void)fetchObjectsWithAssemble:(id<AssembleDelegate>)anAssemble
 andCompletion:(jCompletion)theCompletion
 {
 _delegate = anAssemble;
 _completion = theCompletion;
 
 [self doRequestWithAssemble:self andCompletion:_completion];
 }
 */

- (void)fetchObjectsInBackground:(jCompletion)completion
{
    _completion = completion;
    [self doRequestWithAssemble:self];
}

- (void)fetchObjectsInBackground
{
    [self doRequestWithAssemble:self];
}

- (void)doRequestWithAssemble:(id<AssembleDelegate>)anAssemble
{
    //判断网络条件
    if ([reach currentReachabilityStatus]!=NotReachable) {
        _lock = YES;
        NSString *urlStr;
        if (self.enablePaging) {
            if ([_action rangeOfString:@"?"].location==NSNotFound) {
                _action = [_action stringByAppendingString:@"?"];
            }
            urlStr = [NSString stringWithFormat:@"%@&page=%ld&limit=%ld",_action,page,_limit];
        }else{
            urlStr = _action;
        }
        NSURL *url = [NSURL URLWithString:urlStr];
        if (request) {
            [request clearDelegatesAndCancel];
        }
        request = [[ASIHTTPRequest alloc] initWithURL:url];
        request.delegate = self;
        [request startAsynchronous];
    }else{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            _lock = NO;
            if (_completion) {
                _completion(nil,@"无网络连接",NO,NO);
            }else if([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
                [self.delegate fetcher:self fetchResult:nil error:@"无网络连接" authorization:NO hasMore:NO];
            }
        });
        
    }
    
}

- (void)nextPage
{
    if (!_lock) {
        
        if (_hasMore) {
            _lock = YES;
            page++;
            [self doRequestWithAssemble:self];
        }else{
            if (_completion) {
                _completion(nil,nil,NO,NO);
            }else if([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
                [self.delegate fetcher:self fetchResult:nil error:nil authorization:NO hasMore:NO];
            }
        }
    }
}

- (void)refresh
{
    _hasMore = YES;
    page = 1;
    _lock = NO;
    [request cancel];
    [self doRequestWithAssemble:self];
}

- (void)cancel
{
    [request clearDelegatesAndCancel];
}

#pragma mark - ASIHttpRequestDelegate

- (void)requestFinished:(ASIHTTPRequest *)theRequest
{
    _lock = NO;
    int statusCode = [theRequest responseStatusCode];
    NSString *msg ;
    BOOL isContinue = NO;
    //判断statusCode
    switch (statusCode) {
        case 200:
            msg = @"服务器成功处理请求";
            isContinue = YES;
            break;
        case 301:
            msg = @"永久重定向";
            break;
        case 302:
            msg = @"对象临时移走";
            break;
        case 401:
            msg = @"验证失败";
            break;
        case 403:
            msg = @"服务器拒绝访问";
            break;
        case 404:
            msg = @"服务器找不到请求的网页";
            break;
        case 408:
            msg = @"请求超时";
            break;
        case 413:
            msg = @"请求实体过大";
            break;
        case 414:
            msg = @"请求的URL过长";
            break;
        case 500:
            msg = @"内部服务器错误";
            break;
        case 503:
            msg = @"服务不可用";
            break;
        case 504:
            msg = @"网关超时";
            break;
            
        default:
            msg = @"";
            break;
    }
    
    if (isContinue) {
        NSData *responseData = [theRequest responseData];
        BOOL authorization;
        NSError *error = nil;
        if ([self respondsToSelector:@selector(assemble:authorization:error:)]) {
            NSArray *objects = [self assemble:responseData authorization:&authorization error:&error];
            if (!error) {
                
                if (objects.count==0 ||( objects.count != 0 && objects.count % _limit!=0)) {
                    _hasMore = NO;
                }
                
                if (_completion) {
                    _completion(objects,nil,authorization,_hasMore);
                }
                if ([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
                    [self.delegate fetcher:self fetchResult:objects error:nil authorization:authorization hasMore:_hasMore];
                }
                
            }else{
                if (_completion) {
                    _completion(nil,[error.userInfo objectForKey:@"NSLocalizedDescription"],NO,NO);
                }
                if ([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
                    [self.delegate fetcher:self fetchResult:nil error:[error.userInfo objectForKey:@"NSLocalizedDescription"] authorization:NO hasMore:NO];
                }
            }
        }else{
            if (_completion) {
                _completion(nil,@"assmbleDelegate 没有被实现",NO,NO);
            }
            if ([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
                [self.delegate fetcher:self fetchResult:nil error:@"assmbleDelegate 没有被实现" authorization:NO hasMore:_hasMore];
            }
        }
    }else{
        if (_completion) {
            _completion(nil,msg,NO,NO);
        }
        if ([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
            [self.delegate fetcher:self fetchResult:nil error:msg authorization:NO hasMore:_hasMore];
        }
    }
}

- (void)requestFailed:(ASIHTTPRequest *)theRequest

{
    _lock = NO;
    NSError *error = [theRequest error];
    NSString *msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
    self.page--;
    if (_completion) {
        _completion(nil,msg,NO,NO);
    }
    if ([self.delegate respondsToSelector:@selector(fetcher:fetchResult:error:authorization:hasMore:)]){
        [self.delegate fetcher:self fetchResult:nil error:msg authorization:NO hasMore:_hasMore];
    }
}

- (NSArray *)assemble:(NSData *)data authorization:(BOOL *)flag error:(NSError *__autoreleasing *)error
{
    //等待子类实现
    return nil;
}

#pragma mark 等待子类实现
- (NSArray *)assemble:(NSData *)data authorization:(BOOL *)flag errorMsg:(NSError *__autoreleasing *)error
{
    
    return nil;
}

#pragma mark 发送异步请求
+ (void)sendAsynchronousRequest:(NSString *)url queue:(ASINetworkQueue *)queue completionHandler:(void (^)(ASIHTTPRequest *, NSDictionary *, NSString *))handler
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"%@",url);
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:url]];
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    __weak ASIHTTPRequest *weakRequest = request;
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            NSString *msg ;
            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                    
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            NSDictionary *json ;
            if (isContinue) {
                NSError *error;
                json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
                if (error) {
                    msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                }
            }
            handler(weakRequest,json,msg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    
    [request startAsynchronous];
    
}
+ (void)sendAsynchronousRequest:(NSString *)url cachePolicy:(ASICachePolicy)cachePolicy queue:(ASINetworkQueue *)queue completionHandlerWithData:(void (^)(ASIHTTPRequest *request, NSData *data, NSString *errorMsg))handler
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:url]];
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    request.cachePolicy = cachePolicy;
    __weak ASIHTTPRequest *weakRequest = request;
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            NSString *msg ;
            NSData *data;
            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                    
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            if (isContinue) {
                data = [weakRequest responseData];
            }
            handler(weakRequest,data,msg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    
    [request startAsynchronous];
}

+ (void)sendAsynchronousRequest:(NSString *)url cachePolicy:(ASICachePolicy)cachePolicy queue:(ASINetworkQueue *)queue completionHandlerWithDictionary:(void (^)(ASIHTTPRequest *requset, NSDictionary *json, NSString *errorMsg))handler
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"%@",url);
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:url]];
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    request.cachePolicy = cachePolicy;
    __weak ASIHTTPRequest *weakRequest = request;
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            NSString *msg ;
            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                    
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            NSDictionary *json ;
            if (isContinue) {
                NSError *error;
                json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
                if (error) {
                    msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                }
            }
            handler(weakRequest,json,msg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    
    [request startAsynchronous];
}

+ (void)requsetAndCacheImageLazy:(NSString *)picturePath queue:(ASINetworkQueue *)queue
                  completion:(void(^)(ASIHTTPRequest *request , UIImage *image , NSString *errorMsg))handler
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    picturePath = [picturePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //    NSLog(@"%@",picturePath);
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:picturePath]];

    //判断缓存中是否存在
    NSData *imageData = [[self downloadCache] cachedResponseDataForURL:[NSURL URLWithString:picturePath]];
    if (imageData) {
        if (handler) {
            handler(request,[UIImage imageWithData:imageData],nil);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
        return;
    }
    
    
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    [queue addOperation:request];
    request.downloadCache = [self downloadCache];
    __weak ASIHTTPRequest *weakRequest = request;
    
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            UIImage *image;
            NSString *msg ;
            
            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            if (isContinue) {
                image =[UIImage imageWithData:[weakRequest responseData]];
            }
            handler(weakRequest,image,msg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    
}


+ (void)requsetAndCacheImage:(NSString *)picturePath queue:(ASINetworkQueue *)queue
                  completion:(void(^)(ASIHTTPRequest *request , UIImage *image , NSString *errorMsg))handler
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    picturePath = [picturePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//    NSLog(@"%@",picturePath);
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:picturePath]];
    
    //判断缓存中是否存在
    NSData *imageData = [[self downloadCache] cachedResponseDataForURL:[NSURL URLWithString:picturePath]];
    if (imageData) {
        handler(request,[UIImage imageWithData:imageData],nil);
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
        return;
    }
    
    
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    request.downloadCache = [self downloadCache];
    __weak ASIHTTPRequest *weakRequest = request;
    
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            UIImage *image;
            NSString *msg ;

            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            if (isContinue) {
                image =[UIImage imageWithData:[weakRequest responseData]];
            }
            handler(weakRequest,image,msg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
           [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
           [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
    
    [request startAsynchronous];
}

+ (void)requestAndCacheFile:(NSString *)fileURL queue:(ASINetworkQueue *)queue
                 completion:(void(^)(ASIHTTPRequest *request, NSString* cachedPath, NSString* errorMsg))handler
{
    NSString *cachedPath;
    fileURL = [fileURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *URL = [NSURL URLWithString:fileURL];
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:URL];
    
    //判断缓存中是否存在
    NSData *fileData = [[self downloadCache] cachedResponseDataForURL:URL];
    if (fileData) {
        cachedPath = [[self downloadCache] pathToCachedResponseDataForURL:URL];
        handler(request,cachedPath,nil);
        return;
    }
    
    
    //应该定义成常量
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.queue = queue;
    request.downloadCache = [self downloadCache];
    __weak ASIHTTPRequest *weakRequest = request;
    
    [request setCompletionBlock:^(){
        if(handler){
            int statusCode = [weakRequest responseStatusCode];
            NSString *msg ;
            BOOL isContinue = NO;
            //判断statusCode
            switch (statusCode) {
                case 200:
                    isContinue = YES;
                    break;
                default:
                    msg = [self statusStrWithCode:statusCode];
                    break;
            }
            handler(weakRequest,[[self downloadCache] pathToCachedResponseDataForURL:URL],msg);
        }
    }];
    [request setFailedBlock:^(){
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    
    [request startAsynchronous];
}

+ (void)uploadFile:(NSData *)data
          toServer:(NSString *)server
           withKey:(NSString *)key
       contentType:(NSString *)type
             queue:(ASINetworkQueue *)queue
      andParams:(NSDictionary *)params
          complete:(void (^)(ASIFormDataRequest *, NSDictionary *, NSString *))handler
{
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server]];
    [request setRequestMethod:@"POST"];
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.postFormat = ASIMultipartFormDataPostFormat;
    //设置Post数据
    [self setupParamsWithRequest:request params:params];
    
    NSString *str = [[NSDate date]description];
    [request addData:data withFileName:[self md5:str] andContentType:type forKey:key];
    
    [request buildRequestHeaders];
    
    __weak ASIFormDataRequest *weakRequest = request;
    
    
    [request setCompletionBlock:^{
        int statusCode = [weakRequest responseStatusCode];
        NSString *msg ;
        
        BOOL isContinue = NO;
        //判断statusCode
        switch (statusCode) {
            case 200:
                isContinue = YES;
                break;
            default:
                msg = [self statusStrWithCode:statusCode];
                break;
        }
        if (isContinue && handler) {
            NSError *error;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
            if (error) {
                msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                handler(weakRequest,nil,msg);
            }else{
                handler(weakRequest,json,nil);
            }
            
        }else{
            handler(weakRequest,nil,msg);
        }
    }];
    [request setFailedBlock:^{
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    request.queue = queue;
    
    [request startAsynchronous];

}

+ (void)setupParamsWithRequest:(ASIFormDataRequest *)request params:(NSDictionary *)params
{
    for (NSString *key in params.allKeys) {
        [request setPostValue:[params objectForKey:key] forKey:key];
    }
}

+ (void)postParams:(NSDictionary *)params
         toServer:(NSString *)server
            queue:(ASINetworkQueue *)queue
         complete:(void(^)(ASIFormDataRequest *request,NSDictionary *json,NSString *errorMsg))handler
{
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server]];
    [request setRequestMethod:@"POST"];
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.postFormat = ASIURLEncodedPostFormat;
    //设置Post数据
    
    [self setupParamsWithRequest:request params:params];
    //设置request参数
    
    [request buildRequestHeaders];
    
    __weak ASIFormDataRequest *weakRequest = request;
    
    
    [request setCompletionBlock:^{
        int statusCode = [weakRequest responseStatusCode];
        NSString *msg ;
        
        BOOL isContinue = NO;
        //判断statusCode
        switch (statusCode) {
            case 200:
                isContinue = YES;
                break;
            default:
                msg = [self statusStrWithCode:statusCode];
                break;
        }
        if (isContinue && handler) {
            NSError *error;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
            if (error) {
                msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                handler(weakRequest,nil,msg);
            }else{
                handler(weakRequest,json,nil);
            }
            
        }else{
            if (handler) {
                handler(weakRequest,nil,msg);
            }
        }
    }];
    [request setFailedBlock:^{
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    request.queue = queue;
    
    [request startAsynchronous];
}

#pragma UploadFiles
+ (void)uploadFiles:(NSArray *)datas
           toServer:(NSString *)server
            withKey:(NSString *)key
        contentType:(NSString *)type
              queue:(ASINetworkQueue *)queue
       andParams:(NSDictionary *)params
           complete:(void (^)(ASIFormDataRequest *, NSDictionary *, NSString *))handler
{
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server]];
    [request setRequestMethod:@"POST"];
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.postFormat = ASIMultipartFormDataPostFormat;
    //设置Post数据
    [self setupParamsWithRequest:request params:params];
    
    NSString *str;
    for (NSData *data in datas) {
        str = [[NSDate date] description];
        [request addData:data withFileName:[self md5:str] andContentType:type forKey:key];
    }
    
    
    [request buildRequestHeaders];
    
    __weak ASIFormDataRequest *weakRequest = request;
    
    
    [request setCompletionBlock:^{
        int statusCode = [weakRequest responseStatusCode];
        NSString *msg ;
        
        BOOL isContinue = NO;
        //判断statusCode
        switch (statusCode) {
            case 200:
                isContinue = YES;
                break;
            default:
                msg = [self statusStrWithCode:statusCode];
                break;
        }
        if (isContinue && handler) {
            NSError *error;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
            if (error) {
                msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                handler(weakRequest,nil,msg);
            }else{
                handler(weakRequest,json,nil);
            }
            
        }else{
            if (handler) {
                handler(weakRequest,nil,msg);
            }
        }
    }];
    [request setFailedBlock:^{
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    request.queue = queue;
    
    [request startAsynchronous];
    
}

+ (void)uploadFilesByName:(NSArray *)filenames
                        prefix:(NSString*)prefix
                      toServer:(NSString *)server
                       withKey:(NSString *)key
                   contentType:(NSString *)type
                         queue:(ASINetworkQueue *)queue
                  andParams:(NSDictionary *)params
                      complete:(void (^)(ASIFormDataRequest *request, NSDictionary *json, NSString *errorMsg))handler
{
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server]];
    [request setRequestMethod:@"POST"];
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    request.postFormat = ASIMultipartFormDataPostFormat;
    //设置Post数据
    [self setupParamsWithRequest:request params:params];
    
    for (NSString *filename in filenames) {
        [request addData:[NSData dataWithContentsOfFile:[prefix stringByAppendingPathComponent:filename]] withFileName:filename andContentType:type forKey:key];
    }
    
    
    [request buildRequestHeaders];
    
    __weak ASIFormDataRequest *weakRequest = request;
    
    
    [request setCompletionBlock:^{
        int statusCode = [weakRequest responseStatusCode];
        NSString *msg ;
        
        BOOL isContinue = NO;
        //判断statusCode
        switch (statusCode) {
            case 200:
                isContinue = YES;
                break;
            default:
                msg = [self statusStrWithCode:statusCode];
                break;
        }
        if (isContinue && handler) {
            NSError *error;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
            if (error) {
                msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                handler(weakRequest,nil,msg);
            }else{
                handler(weakRequest,json,nil);
            }
            
        }else{
            if (handler) {
                handler(weakRequest,nil,msg);
            }
        }
    }];
    [request setFailedBlock:^{
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    request.queue = queue;
    
    [request startAsynchronous];
    
}

+ (void)sendAsynchronousRequestWithPost:(NSString *)url queue:(ASINetworkQueue *)queue postValue:(NSDictionary *)postValue completionHandlerWithDictionary:(void (^)(ASIHTTPRequest *request, NSDictionary *json, NSString *errorMsg))handler
{
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]];
    request.timeOutSeconds = kDataBossDefaultTimeOut;
    
    [self setupParamsWithRequest:request params:postValue];
    __weak ASIFormDataRequest *weakRequest = request;
    
    [request setCompletionBlock:^{
        int statusCode = [weakRequest responseStatusCode];
        NSString *msg ;
        
        BOOL isContinue = NO;
        //判断statusCode
        switch (statusCode) {
            case 200:
                isContinue = YES;
                break;
            default:
                msg = [self statusStrWithCode:statusCode];
                break;
        }
        if (isContinue && handler) {
            NSError *error;
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData] options:NSJSONReadingMutableContainers error:&error];
            if (error) {
                msg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
                handler(weakRequest,nil,msg);
            }else{
                handler(weakRequest,json,nil);
            }
            
        }else{
            if (handler) {
                handler(weakRequest,nil,msg);
            }
        }
    }];
    
    [request setFailedBlock:^{
        if(handler){
            NSError *error = [weakRequest error];
            NSString *errorMsg = [error.userInfo objectForKey:@"NSLocalizedDescription"];
            handler(weakRequest,nil,errorMsg);
        }
    }];
    request.queue = queue;
    
    [request startAsynchronous];
    
}

#pragma mark MD5加密
+ (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; 
}

#pragma mark statusCode
+ (NSString *)statusStrWithCode:(int)statusCode
{
    NSString *msg;
    switch (statusCode) {
        case 301:
            msg = @"永久重定向";
            break;
        case 302:
            msg = @"对象临时移走";
            break;
        case 401:
            msg = @"验证失败";
            break;
        case 403:
            msg = @"服务器拒绝访问";
            break;
        case 404:
            msg = @"服务器找不到请求的网页";
            break;
        case 408:
            msg = @"请求超时";
            break;
        case 413:
            msg = @"请求实体过大";
            break;
        case 414:
            msg = @"请求的URL过长";
            break;
        case 500:
            msg = @"内部服务器错误";
            break;
        case 503:
            msg = @"服务不可用";
            break;
        case 504:
            msg = @"网关超时";
            break;
    }
    return msg;
}

#pragma mark 设置缓存路径
+ (ASIDownloadCache*)downloadCache
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        downloadCache = [[ASIDownloadCache alloc] init];
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        [downloadCache setStoragePath:[path stringByAppendingPathComponent:@"resource"]];
        [downloadCache setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
    });
    return downloadCache;
}

- (void)dealloc
{
    NSLog(@"dealloc");
    [request clearDelegatesAndCancel];
}

@end
